import { clamp, copyObj, handlerInputKeyup, makeDiv } from "../core/utils/utils";
import { Vector } from "../core/utils/vector";
import MapSiteModules from "../game/maps/get_map_site";
import mapData from '../game/maps/defines/map.json'
import { ClickDetector } from "../core/utils/click_detector";
import { compressX64 } from "../core/utils/lzstring";
import { compressionPrefix } from "../core/utils/read_write_proxy";

export default {
  handlerInput(){
    handlerInputKeyup(this.htmlElement.querySelector('#worldNameInput'), val => {
      this.mapClip.worldName = val;
    })
    handlerInputKeyup(this.htmlElement.querySelector('#worldDescInput'), val => {
      this.mapClip.worldDesc = val;
    })

    let versionInput = this.htmlElement.querySelector('#mapVersionInput');
    versionInput.value = this.mapData.version;
    handlerInputKeyup(versionInput, val => {
      this.mapData.version = val;
    })

    this.trackClicks(this.htmlElement.querySelector('#mapKeyInput'), () => {
      let { optionSelected } = this.dialogs.showOptionChooser('选择地板类型', {
        active: this.mapSite.key,
        options: Object.keys(MapSiteModules).map(key => ({
          value: key,
          text: key,
          desc: ''
        }))
      })

      optionSelected.add(value => {
        this.mapSite.key = value;
        this.renderView(false);
        this.renderMapSitePanel();
        // this.moveGrid(this.mapSite.mapPos)
      })
    })
  },

  handlerRightmenu(){
    let mapWrapper = this.htmlElement.querySelector('.map-wrapper');
    let rightmenu = this.htmlElement.querySelector('.rightmenu')

    mapWrapper.addEventListener('mousedown', ev => {
      if(ev.button === 2){
        rightmenu.classList.add('show');
        rightmenu.style.left = ev.clientX + 'px';
        rightmenu.style.top = ev.clientY + 'px';
      } else {
        rightmenu.classList.remove('show');
      }
    })
  },

  handlerButtonCallback(){
    let rightmenu = this.htmlElement.querySelector('.rightmenu')

    this.trackClicks(this.htmlElement.querySelector('.homeButton'), () => {
      let { ok } = this.dialogs.showWarning('警告', 
        '是否确认前往首页，所有未保存的数据将被清除。', 
        ['cancel:bad:取消', 'ok:good:确认']
      );

      ok.add(() => {
        this.moveToState('MainMenuState')
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.resetButton'), () => {
      let { ok } = this.dialogs.showWarning('警告', 
        '是否确认重置数据，一旦重置，所有未保存的数据将被清除。', 
        ['cancel:bad:取消', 'ok:good:确认']
      );

      ok.add(() => {
        this.mapData = copyObj(JSON.parse(decompressX64(mapData.data)));
        this.mapClip = null;
        this.renderView();
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.mapButton'), () => {
      let prevMapClip = this.mapClip;
      this.mapClip = null;
      this.renderView(false);
      this.moveGrid(prevMapClip ? prevMapClip.worldPos : [0, 0]);
      prevMapClip = null;
    })

    this.trackClicks(this.htmlElement.querySelector('.create1Next'), () => {
      this.createLine(1);
    })

    this.trackClicks(this.htmlElement.querySelector('.create2Next'), () => {
      this.createLine(2);
    })

    this.trackClicks(this.htmlElement.querySelector('.saveButton'), () => {
      let { ok } = this.dialogs.showInfo('提示', '是否确认保存', ['cancel:bad:取消', 'ok:success:保存']);

      ok.add(() => {
        let closeLoading = this.dialogs.showLoadingDialog('保存中...');
        let mapData = compressX64(JSON.stringify(this.mapData));
        this.app.api.saveMap(this.mapData.version, mapData).then(() => {
          this.dialogs.showInfo('提示', '保存成功');
          closeLoading();
        }).catch(() => {
          this.dialogs.showWarning('警告', '保存失败');
          closeLoading();
        })
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.createNode'), () => {
      rightmenu.classList.remove('show')
      const createNodeDialog = this.dialogs.showInput('创建节点', [
        {
          text: 'x: col',
          key: 'x',
          value: this.currentPos[0]
        },
        {
          text: 'y: row',
          key: 'y',
          value: this.currentPos[1]
        }
      ])

      createNodeDialog.confirm.add(data => {
        this.createNode(data.x, data.y)
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.deleteNode'), () => {
      rightmenu.classList.remove('show')
      const createNodeDialog = this.dialogs.showInput('删除节点', [
        {
          text: 'x: col',
          key: 'x',
          value: this.currentPos[0]
        },
        {
          text: 'y: row',
          key: 'y',
          value: this.currentPos[1]
        }
      ])

      createNodeDialog.confirm.add(data => {
        this.deleteNode(data.x, data.y)
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.directCreateNode'), () => {
      rightmenu.classList.remove('show')

      this.createNode(this.currentPos[0], this.currentPos[1])
    })

    this.trackClicks(this.htmlElement.querySelector('.directDeleteNode'), () => {
      rightmenu.classList.remove('show');

      this.deleteNode(this.currentPos[0], this.currentPos[1])
    })

    this.trackClicks(this.htmlElement.querySelector('.nextMapClip'), () => {
      let { ok } = this.dialogs.showInfo('提示', '你确认修改地图块指向吗？', ['cancel:bad:取消', 'ok:good:确认']);

      ok.add(() => {
        let prevMapClip = this.mapClip;
        this.mapClip = null;
        this.renderView(false, false);
        this.moveGrid(prevMapClip.worldPos)
        this.useEditMode((mapClip, mapSite) => {
          this.mapSite.attr.goWorld = {
            worldPos: mapClip.worldPos,
            mapPos: mapSite.mapPos
          }

          this.dialogs.showInfo('提示', '世界块指向创建完成');
          this.mapClip = prevMapClip;
          prevMapClip = null;
          
          this.renderView(false, false);
          this.renderMapSitePanel();
          this.moveGrid(this.mapSite.mapPos);
        })
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.removeGoMapClip'), () => {
      let { ok } = this.dialogs.showWarning('警告', '你确认移除地图块指向吗？', ['cancel:bad:取消', 'ok:good:确认']);

      ok.add(() => {
        this.mapSite.attr.goWorld = null;
        this.dialogs.showInfo('提示', '世界块指向移除成功');
        this.renderMapSitePanel();
      })
    })

    this.trackClicks(this.htmlElement.querySelector('.addNpc'), () => {
      this.addNpc();
    })

    this.trackClicks(this.htmlElement.querySelector('.addMNpc'), () => {
      this.addNpc(true);
    })

    this.trackClicks(this.htmlElement.querySelector('.addGood'), () => {
      this.addGood();
    })

    this.trackClicks(this.htmlElement.querySelector('.addMGood'), () => {
      this.addGood(true);
    })

    this.trackClicks(this.htmlElement.querySelector('.closeEditMode'), () => {
      this.htmlElement.querySelector('.tip').innerHTML = '';
      this.editMode = false;
      this.mEditMode = false;
      
      this.editModeCb && this.editModeCb();
      this.editModeCb = null;
      this.activeMaps = [];

      this.renderView(false)
    })
  },

  handlerMapMove(){
    let point = this.htmlElement.querySelector('.point')
    let mapWrapper = this.htmlElement.querySelector('.map-wrapper');
    let mapDom = this.htmlElement.querySelector('.map')
    let mouse = new Vector(0, 0);
    let movePos = new Vector(0, 0);
    let mouseDown = false;
    let x = this.moveX;
    let y = this.moveY;

    let detector = new ClickDetector(mapWrapper, {
      captureTouchmove: true,
      applyCssClass: ''
    })

    detector.touchstart.add(pos => {
      mouseDown = true;
      mouse = new Vector(pos.x, pos.y);
    })
    detector.touchmove.add((pos, ev) => {
      this.renderPoint(pos);

      if(!mouseDown) return;
      
      movePos = mouse.sub(new Vector(pos.x, pos.y));

      x = this.moveX - movePos.x;
      y = this.moveY - movePos.y;
      
      mapDom.style.transform = `translate(${x}px, ${y}px) scale(${this.scale})`;
    })
    detector.touchend.add(ev => {
      mouseDown = false;
      this.moveX -= movePos.x;
      this.moveY -= movePos.y;
      movePos = new Vector(0, 0);
      point.innerHTML = '';
    })
    detector.touchout.add(() => {
      detector.touchend.dispatch();
    })

    mapWrapper.addEventListener('mousewheel', ev => {
      let angle = ev.deltaY > 0 ? -1 : 1;

      this.scale = clamp(this.scale + (angle * .05), .2, 2);
      mapDom.style.transform = `translate(${x}px, ${y}px) scale(${this.scale})`;
      this.renderPoint(ev);
    })
  },
}